package com.dataStructures.linearlist;

import java.lang.reflect.Array;
import java.util.Arrays;

public class LinearListImpl<E> implements  LinearList<E> {

    private Object[] elementDatas;
    private int initCapacity = 10;
    private final int expansionFactor = 5;
    private int length = 0; //记录 elementData 的长度.

    public LinearListImpl(){
        elementDatas = new Object[10];
    }

    //扩容.
    private void grow(int minSize){
        if (minSize > expansionFactor){
            minSize = (minSize + expansionFactor) / 2;
        } else {
            minSize = expansionFactor;
        }
        Object[] copy = new Object[initCapacity + minSize];
        System.arraycopy(elementDatas, 0, copy, 0, initCapacity);

        this.elementDatas = copy;
        initCapacity += minSize;
    }
    public void delete(E t) {
        int index = index(t);
        if (index != -1){
            delete(index);
        }
    }

    public void delete(int index) {
        if (index < 0  || index > length - 1 ){
            throw new IndexOutOfBoundsException("index is out of bounds : index : " + index +
                    "length is : " + length);
        }

        E e = elementAt(index);

        int j = length - index - 1;
        //位移逻辑数组, 删除一个位置, System.arraycopy(elementData, index + 1, elementData, index, j);
        System.arraycopy(elementDatas, index + 1, elementDatas, index, j);

        //设置最后一个设置为 null, 等待回收
        elementDatas[length - 1] = null;
    }

    public int insert(int index, E t) {
        if (index > initCapacity){
            grow(index);
        }

        //增加一个位置.
        int j = length - index;
        System.arraycopy(elementDatas, index, elementDatas, index + 1, j);


        elementDatas[index] = t;
        return index;
    }

    public int addElement(E t) {
        if (length == initCapacity -1){
            grow(expansionFactor);
        }
        //增加一个位置.
        elementDatas[length] = t;
        length++;
        return length;
    }


    public E preElem(E t) {
        int index = index(t);
        if (index > 0){
            return elementAt(index - 1);
        }
        return null;
    }

    public E nextElem(E t) {
        int index = index(t);
        if (index < length - 1){
            return elementAt(index + 1);
        }
        return null;
    }

    public int index(E t) {
       if (t == null){
           for (int index = 0; index < length; index++){
               if (elementDatas[index] == null){
                   return index;
               }
           }
       } else {
           for (int index = 0; index < length; index++){
               if (t.equals(elementDatas[index])){
                   return index;
               }
           }
       }

       return -1;
    }

    public E get(int index) {
        if (index < 0 || index > length){
            throw new IndexOutOfBoundsException("index is out of bounds : index : " + index +
                    "length is : " + length);
        }

        return elementAt(index);
    }

    public int length() {
        return length;
    }

    //返回当前元素是否是空的.
    public boolean isEmpty() {
        return  elementDatas == null || elementDatas.length == 0;
    }

    //根据length 从前往后, for 循环迭代, 删除每一个参数.
    public void clear() {
        if (length == 0) {
            return;
        }

        for (int index = 0; index < length; index++){
            elementDatas[index] = null;  //gc the element.
        }

    }

    @SuppressWarnings("unchecked")
    private E elementAt(int index){
        return (E) elementDatas[index];
    }

    //没法实现.
    public void destroy() {
    }
}
